#include <stdio.h>
#include <dshow.h>
#include <qedit.h>
#pragma comment(lib,"strmiids.lib")
//#pragma comment(lib,"strmbase.lib")
void EnumDirveInfo(IEnumMoniker*pEnum);
void EnumDirveFormnt(IMoniker*pMoniker);
int main(){
	CoInitialize(NULL);
	ICreateDevEnum*pDevEnum=NULL;
	IEnumMoniker*pAudioEnum=NULL;
	IEnumMoniker*pVideoEnum=NULL;
	HRESULT hr=CoCreateInstance(CLSID_SystemDeviceEnum,NULL,
		CLSCTX_INPROC_SERVER,IID_ICreateDevEnum,(void**)(&pDevEnum));
	if(SUCCEEDED(hr)){
		hr=pDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,&pVideoEnum,0);
		if(hr==NOERROR){
			printf("EnumVideo:\n");
			EnumDirveInfo(pVideoEnum);
		}else{
			printf(TEXT("Sorry, you have no video capture hardware.\r\n\r\n")
			 TEXT("Video capture will not function properly.\n"));
		}
		hr=pDevEnum->CreateClassEnumerator(CLSID_AudioInputDeviceCategory,&pAudioEnum,0);
		if(hr==NOERROR){
			printf("EnumAudio:\n");
			EnumDirveInfo(pAudioEnum);
		}else{
			printf( TEXT("Sorry, you have no audio capture hardware.\r\n\r\n")
			TEXT("Audio capture will not function properly.\n"));
		}
	}else{
		printf("error\n");
	}
	CoUninitialize();
	system("PAUSE");
	return 0;
}

void EnumDirveInfo(IEnumMoniker*pEnum){
	IMoniker *pMoniker=NULL;
	HRESULT hr;
	pEnum->Reset();
//	pEnum->Skip(1);
	while(pEnum->Next(1,&pMoniker,NULL)==S_OK){
		IPropertyBag*pPropBag;
		hr=pMoniker->BindToStorage(0,0,IID_IPropertyBag,(void**)(&pPropBag));
		if (FAILED(hr)){
			pMoniker->Release();
			continue;
		}
		VARIANT varName;
		VariantInit(&varName);
		hr=pPropBag->Read(L"FriendlyName",&varName,0);
		if (SUCCEEDED(hr)){
			CHAR str[10240];
			WideCharToMultiByte(CP_ACP,0,varName.bstrVal,-1,str,10240,NULL,NULL);
			printf("%s\n",str);
			SysFreeString(varName.bstrVal);
		}
		pPropBag->Release();
		EnumDirveFormnt(pMoniker);
		pMoniker->Release();
	}
}

void EnumDirveFormnt(IMoniker*pMoniker){
	 IBaseFilter*pBF=NULL;
	 pMoniker->BindToObject(0,0,IID_IBaseFilter,(void**)&pBF);

	 ICaptureGraphBuilder2*pCapture=NULL;
	 CoCreateInstance(CLSID_CaptureGraphBuilder2,NULL,CLSCTX_INPROC,IID_ICaptureGraphBuilder2,(void**)&pCapture);
     
//	 ISampleGrabber*pSG=NULL;
//	 CoCreateInstance(CLSID_SampleGrabber,NULL,CLSCTX_INPROC_SERVER,IID_ISampleGrabber,(void**)&pSG);
	IAMStreamConfig*pAMSC=NULL;
	 
	HRESULT hr=pCapture->FindInterface(&PIN_CATEGORY_CAPTURE,&MEDIATYPE_Video,pBF,IID_IAMStreamConfig,(void**)&pAMSC);
	if(SUCCEEDED(hr)){
		int iCount=0;
		int iSize=0;
		pAMSC->GetNumberOfCapabilities(&iCount,&iSize);
		printf("Video Count:%d Size:%d %d \n",iCount,iSize,sizeof(VIDEO_STREAM_CONFIG_CAPS));
		int iFormat;
		for(iFormat=0;iFormat<iCount;iFormat++){
			AM_MEDIA_TYPE*pmt=NULL;
			VIDEO_STREAM_CONFIG_CAPS vscc;
			pAMSC->GetStreamCaps(iFormat,&pmt,(byte*)&vscc);
			printf("i:%d Type:%-4s Type:%-4s 0x%08x %lu %lu %dx%d %dx%d\n",
			iFormat,(char*)&pmt->majortype.Data1,(char*)&pmt->subtype.Data1,
			vscc.guid.Data1,
			vscc.MinBitsPerSecond,vscc.MaxBitsPerSecond,
			//vscc.MinFrameInterval,vscc.MaxFrameInterval,
			vscc.InputSize.cx,vscc.InputSize.cy,
			vscc.MaxOutputSize.cx,vscc.MaxOutputSize.cy);
		}
	}else{
	hr=pCapture->FindInterface(&PIN_CATEGORY_CAPTURE,&MEDIATYPE_Audio,pBF,IID_IAMStreamConfig,(void**)&pAMSC);
	if(SUCCEEDED(hr)){
		int iCount=0;
		int iSize=0;
		pAMSC->GetNumberOfCapabilities(&iCount,&iSize);
		printf("Audio Count:%d Size:%d %d\n",iCount,iSize,sizeof(AUDIO_STREAM_CONFIG_CAPS));
		int iFormat;
		for(iFormat=0;iFormat<iCount;iFormat++){
			AM_MEDIA_TYPE*pmt=NULL;
			AUDIO_STREAM_CONFIG_CAPS ascc;
			pAMSC->GetStreamCaps(iFormat,&pmt,(byte*)&ascc);		
			printf("i:%d Type:%-4s Channels:%lu/%lu/%lu Bits:%lu/%lu/%lu Sample:%lu/%lu/%lu\n",
			iFormat,(char*)&pmt->majortype.Data1,
			ascc.MinimumChannels,ascc.MaximumChannels,ascc.ChannelsGranularity,
			ascc.MinimumBitsPerSample,ascc.MaximumBitsPerSample,ascc.BitsPerSampleGranularity,
			ascc.MinimumSampleFrequency,ascc.MaximumSampleFrequency,ascc.SampleFrequencyGranularity);
		}
	}else{
	   printf("GetFailed\n");
	   pBF->Release();
	   pCapture->Release();
	   return;
	}
	}
	pAMSC->Release();
	pBF->Release();
	pCapture->Release();
}